package com.lvhr.rpc.filter;


import com.lvhr.rpc.model.RpcRequest;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

/**
 * NonceValidator实现（防重放攻击）
 */
@Slf4j
public class NonceValidator implements SecurityValidator {
    private static final long MAX_NONCE_AGE = 300_000; // 5分钟有效期（毫秒）
    private static final ConcurrentHashMap<String, Long> nonceCache = new ConcurrentHashMap<>(1024);

    @Override
    public boolean validate(RpcRequest request) throws SecurityException {
        log.debug("开始nonce校验 --------------------------------------");
        String nonce = (String) request.getAttachments().get("X-Nonce");
        if (nonce == null || nonce.isEmpty()) {
            throw new SecurityException(403, "Nonce不能为空");
        }

        // 原子性操作：不存在时放入，存在时返回旧值
        Long existingTime = nonceCache.putIfAbsent(nonce, System.currentTimeMillis());
        if (existingTime != null) {
            throw new SecurityException(403, "请求已重复");
        }

        // 异步清理过期Nonce
        if (nonceCache.size() > 1000) {
            nonceCache.entrySet().removeIf(entry ->
                    System.currentTimeMillis() - entry.getValue() > MAX_NONCE_AGE);
        }
        return true;
    }
}
